package games.mapacman.client;

import games.mapacman.common.Dot;
import games.mapacman.common.EatenSign;
import games.mapacman.common.Fruit;
import games.mapacman.common.Powerpill;
import games.mapacman.common.Superdot;
import games.mapacman.common.ZoneChangePoint;
import games.mapacman.common.consts;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.geom.Point2D;
import java.awt.image.BufferStrategy;
import java.util.Vector;

import javax.swing.JPanel;

import marauroa.common.Log4J;
import marauroa.common.game.RPObject;
import marauroa.server.game.container.PlayerEntryContainer;

/** This class is an abstraction of the game screen, so that we can think of it as
 *  a window to the world, we can move it, place it and draw object usings World 
 *  coordinates.
 *  This class is based on the singleton pattern. */
public class GameScreen 
{
	private static final marauroa.common.Logger logger = Log4J.getLogger(GameScreen.class);

  /** One unit is 24 pixels */
  public final static int PIXEL_SCALE=24;
  
  /** Minimum distance from player to screen border in world units */
  public final static int MIN_DISTANCE=5;
  
  /** The amount of pixels screen moves each nextFrame() */
  public final static int PIXEL_MOVES=9;
  
  /** The amount of frames that should be scrolled even if the player is still placed in the limit*/
  public final static int SCROLL_MORE=7;
  
  /** how many Pixels should a item between 2 worldunits move per frame */
  public double movePixelsPerFrame = 8d;
	  
  
  private BufferStrategy strategy;
  private Graphics2D g;
  private Image background;
  
  /** Actual rendering position of the leftmost top corner in world units*/
  private double x,y;
  /** Actual speed of the screen */
  private double dx,dy;
  /** Actual size of the screen in pixels */
  private int sw,sh;  
  /** Actual size of the world in world units */
  private int ww,wh;
  
  private Images ImageList;
  private RPObject myPlayer;
  private String myPlayerName;
  private int myScore;
  private String highestPlayer;
  private int highestScore;
  
  // to paint the first 5 frames complete
  private int paintCounter=-5;
  
  private int[][] walls;
  private Dot[][] dots;
  
  private static GameScreen screen;
  private Sprite[] sprite_wall;
  private Sprite wall_sprite;
  private Vector<Sprite> sprite_mplayer;
  private Vector<Sprite> sprite_oplayer;
  private Vector<Sprite> sprite_pplayer;
  private Sprite sprite_dot;
  private Sprite sprite_superdot;
  private Vector<Sprite> sprite_fruit;
  private Sprite sprite_powerpill;
  private Sprite sprite_zonechange;
  private Vector<Sprite> sprite_EatenSprite;
  private Vector<Sprite> sprite_GhostR;
  private Vector<Sprite> sprite_GhostG;
  private Vector<RPObject> Players;
  private Vector<RPObject> Ghosts;
  private Vector<EatenSign> EatenSigns;
  private Vector<String> ChatMessages;
  private Vector<ZoneChangePoint> zoneChangePoints;
  private int scrollInt=0;

  private boolean scrolledInLastTurn=false;
  
  
  /** Create a screen with the given width and height */
	  public static void createScreen(BufferStrategy strategy, int sw, int sh,int wuWidth, int wuHeight, JPanel panel, String charname)
	    {
	    if(screen==null)
	      {
	      screen=new GameScreen(strategy,sw,sh,wuWidth,wuHeight,panel,charname);
	      }
	    }
  
  /** Returns the GameScreen object */
  public static GameScreen get()
    {
    return screen;
    }
  
  
  private GameScreen(BufferStrategy strategy, int sw, int sh,int wuWidth, int wuHeight, JPanel panel, String charname)
    {
	
	  // needed for splitting Images to multpile sprites
	GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
	  
	  
	ChatMessages = new Vector<String>();
	zoneChangePoints = new Vector<ZoneChangePoint>();
	EatenSigns = new Vector<EatenSign>();
	ww=wuWidth;
	wh=wuHeight;
	clear();
	
    this.sw=sw;
    this.sh=sh;
	this.myPlayerName = charname;
	//	INIT IMAGES !!
	ImageList = new Images(panel);
	// Walls
	this.wall_sprite = new Sprite(ImageList.getImage("wall0"));
	this.sprite_wall = new Sprite[16];
	for (int i=0;i<=15;i++)
	{
		this.sprite_wall[i]= new Sprite(ImageList.getImage("wall"+i));
	}
	// Dots, Sueprdots, Powerpills
	this.sprite_dot = new Sprite(ImageList.getImage("dot"));	
	this.sprite_superdot = new Sprite(ImageList.getImage("superdot"));
	this.sprite_powerpill = new Sprite(ImageList.getImage("powerpill"));
	
	// Fruits
	this.sprite_fruit = new Vector<Sprite>();
	Sprite tempSprite = new Sprite(ImageList.getImage("fruits"));
	for (int i=0;i<=13;i++)
    {
        Image image = gc.createCompatibleImage(PIXEL_SCALE,PIXEL_SCALE,Transparency.BITMASK);
        tempSprite.draw(image.getGraphics(),0,0,i*PIXEL_SCALE,0);
        sprite_fruit.add(new Sprite(image));
    }
	
	// KILLed Sprite
	this.sprite_EatenSprite = new Vector<Sprite>(); 
	tempSprite = new Sprite(ImageList.getImage("eatensign"));
	for (int i=0;i<=2;i++)
    {
        Image image = gc.createCompatibleImage(PIXEL_SCALE,PIXEL_SCALE,Transparency.BITMASK);
        tempSprite.draw(image.getGraphics(),0,0,i*PIXEL_SCALE,0);
        sprite_EatenSprite.add(new Sprite(image));
    }
	
	// ZoneChangePoints
	this.sprite_zonechange = new Sprite(ImageList.getImage("zonechange"));
	// add Ghost sprites	
	this.sprite_GhostR = new Vector<Sprite>();
	tempSprite = new Sprite(ImageList.getImage("GhostR"));
	for (int i=0;i<=9;i++)
    {
        Image image = gc.createCompatibleImage(PIXEL_SCALE,PIXEL_SCALE,Transparency.BITMASK);
        tempSprite.draw(image.getGraphics(),0,0,i*PIXEL_SCALE,0);
        sprite_GhostR.add(new Sprite(image));
    }
	
	this.sprite_GhostG = new Vector<Sprite>();
	tempSprite = new Sprite(ImageList.getImage("GhostG"));
	for (int i=0;i<=9;i++)
    {
        Image image = gc.createCompatibleImage(PIXEL_SCALE,PIXEL_SCALE,Transparency.BITMASK);
        tempSprite.draw(image.getGraphics(),0,0,i*PIXEL_SCALE,0);
        sprite_GhostG.add(new Sprite(image));
    }
	
	// add Player Images
	// for my Player
	this.sprite_mplayer = new Vector<Sprite>();
	tempSprite = new Sprite(ImageList.getImage("mplayer"));
	for (int i=0;i<=13;i++)
    {
        Image image = gc.createCompatibleImage(PIXEL_SCALE,PIXEL_SCALE,Transparency.BITMASK);
        tempSprite.draw(image.getGraphics(),0,0,i*PIXEL_SCALE,0);
        sprite_mplayer.add(new Sprite(image));
    }
	// and other Players
	this.sprite_oplayer = new Vector<Sprite>();
	tempSprite = new Sprite(ImageList.getImage("oplayer"));
	for (int i=0;i<=13;i++)
    {
        Image image = gc.createCompatibleImage(PIXEL_SCALE,PIXEL_SCALE,Transparency.BITMASK);
        tempSprite.draw(image.getGraphics(),0,0,i*PIXEL_SCALE,0);
        sprite_oplayer.add(new Sprite(image));
    }	
	// and other Players
	this.sprite_pplayer = new Vector<Sprite>();
	tempSprite = new Sprite(ImageList.getImage("pplayer"));
	for (int i=0;i<=13;i++)
    {
        Image image = gc.createCompatibleImage(PIXEL_SCALE,PIXEL_SCALE,Transparency.BITMASK);
        tempSprite.draw(image.getGraphics(),0,0,i*PIXEL_SCALE,0);
        sprite_pplayer.add(new Sprite(image));
    }	
	// ALL IMAGES ADDED
	
	
    x=y=0;
    dx=dy=0;
	g=(Graphics2D) strategy.getDrawGraphics();
	g.setBackground(Color.black);
	this.strategy = strategy;
	
	g.setColor(Color.black);
	g.fillRect(0,0,sw,sh);
    }
  
  /** Prepare screen for the next frame to be rendered and move it if needed */
  public void nextFrame()
  {
  logger.info("GameScreen::nextFrame >");
	  
  if (myPlayer!=null)
  {	  // Do SCROLLING if necessary
	  int PlayerX=myPlayer.getInt("x");
	  int PlayerY=myPlayer.getInt("y");
	  boolean scrolled=false;
	  if (!isInScreen(PlayerX,PlayerY))
	  {
		  place(PlayerX,PlayerY);
		  paintCounter=0;
	  }
	  else 
	  {
		  if ( PlayerX>=(x-MIN_DISTANCE+sw/PIXEL_SCALE))
		  {
			  dx=PIXEL_MOVES;
			  scrollInt=SCROLL_MORE;
			  scrolled=true;
		  }
		  else if ( PlayerX<=(x+MIN_DISTANCE) && x>0)
		  {
			  dx=-PIXEL_MOVES;
			  scrollInt=SCROLL_MORE;
			  scrolled=true;
		  }
		  
		  if ( PlayerY>=(y-MIN_DISTANCE+sh/PIXEL_SCALE))
		  {
			  dy=PIXEL_MOVES;
			  scrollInt=SCROLL_MORE;
			  scrolled=true;
		  }
		  else if ( PlayerY<=(y+MIN_DISTANCE) && y>0)
		  {
			  dy=-PIXEL_MOVES;
			  scrollInt=SCROLL_MORE;
			  scrolled=true;
		  }
	  }
	  if (!scrolled) 
	  {
		  if (scrollInt==0 ) 
		  	move(0,0);
		  else
			scrollInt--;
	  }
	  if (scrollInt>0)
		  scrolledInLastTurn=true;
  }


  // clear Area around Player and Ghosts
  for (RPObject object:Players)
  {
	repaintArea(object);
  }
  for (RPObject object:Ghosts)
  {
	repaintArea(object,2);						
  }
  
  // draw ZoneChangePoints
  for (ZoneChangePoint point : zoneChangePoints)
  {
	point.draw(screen,sprite_zonechange);
  }  
  
  // move and paint Players and Ghosts
  for (RPObject object:Players)
  {
	screen.movePlayer(object);
	int move = object.getInt("move");
	if (move<movePixelsPerFrame)
		object.put("move",move+1);
  }
  for (RPObject object:Ghosts)
  {
  	int move = object.getInt("move");
	if (move<movePixelsPerFrame)
		object.put("move",move+1);
	screen.moveGhost(object);						
  }

  // draw EatenSigns
  for (EatenSign sign : EatenSigns)
  {
	  sign.draw(this);  
  }
  
  // remove EatenSigns if they have to disappear
	Vector<EatenSign> deleteEatenSigns = new Vector<EatenSign>();
	for (EatenSign sign : EatenSigns)
	{
		if (!sign.valid())
		{
			deleteEatenSigns.add(sign);
		}
	}
	for (EatenSign sign : deleteEatenSigns)
	{
		EatenSigns.remove(sign);
	}

  
  
  
  // create Info-panel at bottom
  g.setColor(Color.BLACK);
  g.fillRect(0,sh+1,sw,100);
  g.setColor(Color.RED);
  g.drawLine(0,sh,sw,sh);
  // draw Chat Text
  g.setColor(Color.white);
  int pos=19;
  for (String chatText : ChatMessages)
  {
	  g.drawString(chatText,2,sh+pos);
	  pos+=18;
  }
  
  // get Top Score
  for (RPObject object : Players)
  {
	int score = object.getInt("score");
	if (score > highestScore)
	{
		highestScore=score;
		highestPlayer=object.get("name");
	}
	if (object.get("name").equals(myPlayerName))
	{
		myScore=score;
	}
  }
  
  // draw Scores and Chat Window
  g.setColor(Color.BLACK);
  g.fillRect(310,sh+1,sw-310,41);
  g.setColor(Color.RED);
  g.drawLine(320,sh+1,320,sh+40);
  g.drawLine(320,sh+41,sw,sh+41);
  g.drawLine(0,sh,sw,sh);
  g.setColor(Color.white);
  g.drawString("Your Score ("+myPlayerName+") :"+myScore,325,sh+18);
  g.drawString("Top Score ("+highestPlayer+") : "+highestScore,325,sh+36);

  // empty Score
  myScore=0;
  highestPlayer="";
  highestScore=0;
  
  g.dispose();
  strategy.show();
  g=(Graphics2D)strategy.getDrawGraphics();

  // clear Areas around some items ... EatenSigns at example ;)
  for (EatenSign sign : EatenSigns)
  {
	  repaintArea(sign.getX(), sign.getY(),0);
  }
  
  
  if(((x+dx/PIXEL_SCALE>=-PIXEL_SCALE) && dx<0) || ((x+dx/PIXEL_SCALE+getWidth()<=ww) && dx>0))
    {
    x+=dx/PIXEL_SCALE;
    }
  else
    {
    dx=0;
    }
    
  if((y+dy/PIXEL_SCALE>=-PIXEL_SCALE && dy<0) || (y+dy/PIXEL_SCALE+getHeight()<=wh && dy>0))
    {
    y+=dy/PIXEL_SCALE;
    }
  else
    {
    dy=0;
    }
      
  // redraw everything except Players and Ghosts
  // paintCounter to make sure, that whole screen is repaint every 25 frames
  paintCounter--;
  if (paintCounter<0 || dx!=0.0 || dy!=0.0)
  {
	  if (paintCounter==0)
		  paintCounter=25;
	  else
		  paintCounter+=2;
	  paintScreen();
  }
  
  logger.info("GameScreen::nextFrame <");
  }
  
  private void repaintArea(RPObject object) {
	  repaintArea(object,1);
	
}

  private void repaintArea(RPObject object, int border) {
	  repaintArea(object.getInt("x"),object.getInt("y"),border);
	
}

  private boolean isInScreen(int x, int y)
  {
	  if (x<this.x-1 || x>this.x+sw/PIXEL_SCALE+1)
		  return false;
	  if (y<this.y-1 || y>this.y+sh/PIXEL_SCALE+1)
		  return false;
	  // else
	  return true;  
  }
/** Translate to screen coordinates the given world coordinate */
  public Point2D invtranslate(Point2D point)
    {
    double tx=(point.getX()-x)*PIXEL_SCALE;
    double ty=(point.getY()-y)*PIXEL_SCALE;
    return new Point.Double(tx,ty);
    }

public double getWidth()
  {
  return sw/PIXEL_SCALE;
  }

/** Returns screen height in world units */
public double getHeight()
  {
  return sh/PIXEL_SCALE;
  }
 
  /** Returns the Graphics2D object in case you want to operate it directly.
   *  Ex. GUI */
  public Graphics2D expose()
    {
    return g;
    }
  
  /** Indicate the screen windows to move at a dx,dy speed. */
  public void move(double dx, double dy)
    {
    this.dx=dx;
    this.dy=dy;
    }
  
  /** Returns the x speed of the movement */
  public double getdx()
    {
    return dx;
    }

  /** Returns the y speed of the movement */
  public double getdy()
    {
    return dy;
    }

  /** Place the screen at the x,y position of world in world units. */
  public void place(double x, double y)
    {
    this.x=x;
    this.y=y;
    }
  
  /** Sets the world size */
  public void setMaxWorldSize(int width, int height)
    {
    ww=width;
    wh=height;
    }
  
  /** Translate to world coordinates the given screen coordinate */
  public Point2D translate(Point2D point)
    {
    double tx=(point.getX()/PIXEL_SCALE)+x;
    double ty=(point.getY()/PIXEL_SCALE)+y;
    return new Point.Double(tx,ty);
    }

  /** Draw a sprite in screen given its world coordinates */
  public void draw(Sprite sprite,Graphics2D g, double wx, double wy)
    {
    int sx=(int)((wx-x)*PIXEL_SCALE+(PIXEL_SCALE-sprite.getHeight())/2);
    int sy=(int)((wy-y)*PIXEL_SCALE+(PIXEL_SCALE-sprite.getWidth())/2);
    
    if((sx>=-PIXEL_SCALE && sx<sw) && (sy>=-PIXEL_SCALE && sy<sh))
      {
      sprite.draw(g,sx,sy);
      }
    }
  
  /** Draw a sprite in screen given its world coordinates */
  public void draw(Sprite sprite,double wx, double wy){
  	draw(sprite, g,wx,wy);
    }
  
  public Sprite createString(String text, Color textColor)
    {
    GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    Image image = gc.createCompatibleImage(g.getFontMetrics().stringWidth(text),16,Transparency.BITMASK);    
    Graphics g2d=image.getGraphics();

    g2d.setColor(Color.black);
    g2d.drawString(text,-1,9);
    g2d.drawString(text,-1,11);
    g2d.drawString(text,1,9);
    g2d.drawString(text,1,11);

    g2d.setColor(textColor);
    g2d.drawString(text,0,10);
    return new Sprite(image);      
    }

  public Sprite createTextBox(String text, int width, Color textColor, Color fillColor)
    {
    int lineLengthPixels=g.getFontMetrics().stringWidth(text);
    int numLines=(lineLengthPixels/width)+1;
    
    GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    Image image = gc.createCompatibleImage(((lineLengthPixels<width)?lineLengthPixels:width)+4,16*numLines,Transparency.BITMASK);
    
    Graphics g2d=image.getGraphics();
    g2d.setColor(fillColor);
    g2d.fillRect(0,0,((lineLengthPixels<width)?lineLengthPixels:width)+4,16*numLines);

    g2d.setColor(textColor);
    int lineLength=text.length()/numLines;
    for(int i=0;i<numLines;i++)
      {
      String line=text.substring(i*lineLength,(i+1)*lineLength);
      g2d.drawString(line,2,i*16+12);
      }
        
    return new Sprite(image);      
    }

public void addWall(int x, int y)
{
	addWall(x,y,true);
}
  
public void addWall(int x, int y, boolean checkneihgbours)
{
	int walltype=0;
	if (checkneihgbours)
	{
		walls[x][y]=0;
		if (walls[x+1][y]>-1) addWall(x+1,y,false);
		if (walls[x][y+1]>-1) addWall(x,y+1,false);
		if (x>0 && walls[x-1][y]>-1) addWall(x-1,y,false);
		if (y>0 && walls[x][y-1]>-1) addWall(x,y-1,false);
	}
	
	if (y>0 && walls[x][y-1]>-1)walltype+=1;
	if (walls[x+1][y]>-1)walltype+=2;
	if (walls[x][y+1]>-1)walltype+=4;
	if (x>0 && walls[x-1][y]>-1)walltype+=8;
	walls[x][y]=walltype;
}
  

public void drawWall(RPObject object) {
	int x = object.getInt("x");
	int y = object.getInt("y");
	drawWall(x,y);
	
}

public void drawWall(int x, int y) {
	if (x<0 || y<0) return;
	if (isInScreen(x,y))
		if (walls[x][y]>-1)
			draw(sprite_wall[walls[x][y]],g,x,y);
	
}

public void movePlayer(RPObject object) {
	int x = object.getInt("x");
	int y = object.getInt("y");
	
	if (!isInScreen(x,y)) return;
	
	
	int imgCounter = object.getInt("imgCounter");
	if (imgCounter==2)
	{
		object.put("imgCounter",0);
	}
	else
	{
		object.put("imgCounter",imgCounter+1);
	}
	
	//	check for collision
	checkCollisionWithWall(object);
	
	drawPlayer(object);
	

}

private void drawPlayer(RPObject object) {
	int imgCounter = object.getInt("imgCounter");
	int x = object.getInt("x");
	int y = object.getInt("y");
	

	Vector<Sprite> sprite_player;
	if (object.getInt("power")>0)
	{
		sprite_player=sprite_pplayer;
	}
	else if (object==myPlayer)
	{
		sprite_player= sprite_mplayer;
	}
	else
	{
		sprite_player = sprite_oplayer;
	}
	switch(object.getInt("dir"))
	{
	case consts.DIR_NORTH : draw(sprite_player.get((consts.DIR_NORTH*3)+imgCounter+1),g,x,y-(object.getInt("move")/movePixelsPerFrame)); break;
	case consts.DIR_SOUTH : draw(sprite_player.get((consts.DIR_SOUTH*3)+imgCounter+1),g,x,y+(object.getInt("move")/movePixelsPerFrame)); break;
	case consts.DIR_EAST : draw(sprite_player.get((consts.DIR_EAST*3)+imgCounter+1),g,x+(object.getInt("move")/movePixelsPerFrame),y); break;
	case consts.DIR_WEST : draw(sprite_player.get((consts.DIR_WEST*3)+imgCounter+1),g,x-(object.getInt("move")/movePixelsPerFrame),y); break;
	case consts.DIR_NONE : draw(sprite_player.get(0),g,x,y); break;
	}
	
}

private void paintScreen()
{
	g.setColor(Color.black);
	g.fillRect(0,0,sw,sh);
	for (int i=0;i<ww;i++)
	{
		for (int j=0;j<wh;j++)
		{
			drawWall(i,j);
			drawDot(i,j);
		}
	}
}

// repaint part of screen (unit x,y and every surrounding units with distance border
public void repaintArea(int x, int y, int border) {
	g.setColor(Color.black);
	g.fillRect((int)((x-border-this.x)*PIXEL_SCALE),(int)((y-border-this.y)*PIXEL_SCALE),(2*(border)+1)*PIXEL_SCALE,(2*(border)+1)*PIXEL_SCALE);
	for (int i=x-border;i<=x+border;i++)
	{
		for (int j=y-border;j<=y+border;j++)
		{
			drawWall(i,j);
			drawDot(i,j);
		}
	}
}

public void drawDot(int x, int y) {
	if (x<0 || y<0) return;
	if (dots[x][y]!=null && isInScreen(x,y))
	{
		dots[x][y].draw(this);
	}
		
	
}

public void moveGhost(RPObject object) {
	int x = object.getInt("x");
	int y = object.getInt("y");
	
	if (!isInScreen(x,y)) return;
	
	int imgCounter = object.getInt("imgCounter");
	if (imgCounter==1)
	{
		object.put("imgCounter",0);
	}
	else
	{
		object.put("imgCounter",imgCounter+1);
	}

	int dir = object.getInt("dir");
	
	// standard collision check
	checkCollisionWithWall(object);
	
	// check collision with other ghosts
	boolean ghostcollision=false;
	for (RPObject ghost : Ghosts)
	{
		if (ghost != object)
			switch(dir)
			{
			case consts.DIR_NORTH : if (ghost.getInt("x")==x && ghost.getInt("y")==y-1) ghostcollision=true; break;
			case consts.DIR_SOUTH : if (ghost.getInt("x")==x && ghost.getInt("y")==y+1) ghostcollision=true; break;
			case consts.DIR_EAST : if (ghost.getInt("x")==x+1 && ghost.getInt("y")==y) ghostcollision=true; break;
			case consts.DIR_WEST : if (ghost.getInt("x")==x-1 && ghost.getInt("y")==y) ghostcollision=true; break;
			}
	}
	if (ghostcollision)
		object.put("move",0);
	
	Vector<Sprite> sprite_Ghost;
	switch(object.getInt("color"))
	{
		case 0 : sprite_Ghost = sprite_GhostR; break;
		case 1 : sprite_Ghost = sprite_GhostG; break;
		case 2 : sprite_Ghost = sprite_GhostR; break;
		default : sprite_Ghost = sprite_GhostG; break;
	}
	
	switch(dir)
	{
	case consts.DIR_NORTH : draw(sprite_Ghost.get(imgCounter),g,x,y-(object.getInt("move")/movePixelsPerFrame)); break;
	case consts.DIR_SOUTH : draw(sprite_Ghost.get((2*dir)+imgCounter),g,x,y+(object.getInt("move")/movePixelsPerFrame)); break;
	case consts.DIR_EAST : draw(sprite_Ghost.get((2*dir)+imgCounter),g,x+(object.getInt("move")/movePixelsPerFrame),y); break;
	case consts.DIR_WEST : draw(sprite_Ghost.get((2*dir)+imgCounter),g,x-(object.getInt("move")/movePixelsPerFrame),y); break;
	case consts.DIR_NONE : draw(sprite_Ghost.get(8+imgCounter),g,x,y); break;
	}
	
}

private void checkCollisionWithWall(RPObject object) {
	int nextDir = object.getInt("nextdir");
	int x =object.getInt("x");
	int y = object.getInt("y"); 
	
	if (nextDir==consts.DIR_NONE)
	{
		switch(object.getInt("dir"))
		{
			case consts.DIR_NORTH : if (walls[x][y-1]>-1) object.put("dir",consts.DIR_NONE); break;
			case consts.DIR_SOUTH : if (walls[x][y+1]>-1) object.put("dir",consts.DIR_NONE); break;
			case consts.DIR_EAST : if (walls[x+1][y]>-1) object.put("dir",consts.DIR_NONE); break;
			case consts.DIR_WEST : if (walls[x-1][y]>-1) object.put("dir",consts.DIR_NONE); break;
		}
	}
	else
	{
		boolean collision = false;
		switch(nextDir)
		{
			case consts.DIR_NORTH :  if (walls[x][y-1]>-1) collision = true; break;
			case consts.DIR_SOUTH : if (walls[x][y+1]>-1) collision = true; break;
			case consts.DIR_EAST : if (walls[x+1][y]>-1) collision = true; break;
			case consts.DIR_WEST : if (walls[x-1][y]>-1) collision = true; break;
		}
		if (! collision)
		{
			object.put("dir",nextDir);
			object.put("nextdir",consts.DIR_NONE);
		}
	}
	
}

public void setPlayerName(String name)
{
	myPlayerName=name;
}

public void setPlayer(RPObject object) {
	myPlayer = object;
	
}

public void addDot(RPObject object) {
	if (object.getInt("respawn")<1)
    {
		int x = object.getInt("x");
		int y = object.getInt("y");
		if (object.get("type").equals(consts.TYPE_DOT))
		{
			dots[x][y]= new Dot(object);
		}
		else if (object.get("type").equals(consts.TYPE_SUPERDOT))
		{
			dots[x][y]= new Superdot(object);
		}
		else if (object.get("type").equals(consts.TYPE_POWERPILL))
		{
			dots[x][y]= new Powerpill(object);
		}
		else if (object.get("type").equals(consts.TYPE_FRUIT))
		{
			dots[x][y]= new Fruit(object);
		}

		dots[x][y].draw(this);
    }
	else 
		dots[object.getInt("x")][object.getInt("y")]=null;
}

public void setPlayerGhostVector(Vector<RPObject>newPlayerVector,Vector<RPObject>newGhostVector)
{
	Players=newPlayerVector;
	Ghosts=newGhostVector;
}

public void printChatText(String text) {
	if (ChatMessages.size()==2)
		ChatMessages.remove(0);
	ChatMessages.add(text);
	
}

public RPObject getPlayer() {
	return myPlayer;
}

public boolean noScrollinLastTurn() {
	if (scrolledInLastTurn)
	{
		scrolledInLastTurn = false;
		return false;
	}
	else
		return true;
}

public void clear() {
	walls=new int[ww][wh];
	dots=new Dot[ww][wh];
	for (int i=0;i<ww;i++)
	{
		for (int j=0;j<wh;j++)
		{
			walls[i][j]=-1;
			dots[i][j]=null;
		}
	}
	zoneChangePoints.clear();
	
}

public void addZoneChange(ZoneChangePoint object) {
	zoneChangePoints.add(object);
	
}

public Vector<Sprite> getFruitsSprites()
{
	return sprite_fruit;
}

public Sprite getDotSprite(int type_dot) {
	switch (type_dot)
	{	
		case Dot.TYPE_SUPERDOT: return sprite_superdot;
		case Dot.TYPE_FRUIT: return sprite_fruit.get(0);
		case Dot.TYPE_POWERPILL: return sprite_powerpill;
		default: return sprite_dot;
	}
}

public Sprite getKillSprite(int i) {
	return sprite_EatenSprite.get(i);
}
public void addEatenSign(RPObject sign)
{
	EatenSigns.add(new EatenSign(sign));
}

public void removeEatenSign(RPObject object)
{
	System.out.println(object.getInt("delete"));
	if (EatenSigns.size()==1) EatenSigns.clear();
	else
	{
		Vector<EatenSign> deleteEatenSigns = new Vector<EatenSign>();
		for (EatenSign sign : EatenSigns)
		{
			if (sign.getRPObject()==object)
			{
				deleteEatenSigns.add(sign);
			}
		}
		for (EatenSign sign : deleteEatenSigns)
		{
			EatenSigns.remove(sign);
		}
	}
}

}
